package com.linsen.gateway.initializer;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.linsen.core.common.constant.LinsenConstant;
import com.linsen.gateway.handler.SaTokenApiResourcesMappingHandler;
import com.linsen.gateway.props.LinsenApiResourcesMappingProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.yaml.snakeyaml.Yaml;

import javax.annotation.PostConstruct;
import java.util.LinkedHashMap;
import java.util.Properties;
import java.util.concurrent.Executor;

/**
 * @author zhaoyong
 * @date 2023/8/5
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ApiResourcesMappingInitializer {
    private final NacosConfigProperties nacosConfigProperties;

    @PostConstruct
    public void initApiResources() {
        try {
            Properties properties = new Properties();
            properties.put(PropertyKeyConst.SERVER_ADDR, this.nacosConfigProperties.getServerAddr());
            properties.put(PropertyKeyConst.USERNAME, this.nacosConfigProperties.getUsername());
            properties.put(PropertyKeyConst.PASSWORD, this.nacosConfigProperties.getPassword());
            properties.put(PropertyKeyConst.NAMESPACE, this.nacosConfigProperties.getNamespace());
            ConfigService configService = NacosFactory.createConfigService(properties);

            String content = configService.getConfig("linsen-dynamic-api-resources.yaml", this.nacosConfigProperties.getGroup(), LinsenConstant.CONFIG_TIMEOUT_MS);
            log.info("initializer gateway api resources begin");
            this.updateApiResources(content);
            log.info("initializer gateway api resources complete");
            // 开启监听，实现动态
            configService.addListener("linsen-dynamic-api-resources.yaml", this.nacosConfigProperties.getGroup(), new Listener() {
                @Override
                public void receiveConfigInfo(String configInfo) {
                    log.info("update gateway api resources begin");
                    updateApiResources(configInfo);
                    log.info("update gateway api resources complete");
                }

                @Override
                public Executor getExecutor() {
                    return null;
                }
            });
        } catch (NacosException e) {
            log.error("load api resources error: {}", e.getErrMsg());
        }
    }

    public void updateApiResources(String content) {
        Yaml yaml = new Yaml();
        LinsenApiResourcesMappingProperties apiResourcesMappingProperties = yaml.loadAs(content, LinsenApiResourcesMappingProperties.class);
        log.info("load api resources mappings: {}", apiResourcesMappingProperties.getMappings());
        if (CollectionUtil.isEmpty(apiResourcesMappingProperties.getMappings())) {
            SaTokenApiResourcesMappingHandler.setMappings(new LinkedHashMap<>());
            return;
        }

        SaTokenApiResourcesMappingHandler.setMappings(apiResourcesMappingProperties.getMappings());
    }
}
